#include <iostream>
#include <vector>
#include <string>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include "DroneState.h"

void Client::sendMsg(DroneState * msg)
{

	std::string sendString = msg->droneState2Json();
	sendString.append(1,'\0');
	int actualLength = sendString.size();
	int sendLength = actualLength + sizeof(int);
	char sbuf[sendLength];
	memcpy(sbuf, &actualLength,  sizeof(int));
	memmove(sbuf+sizeof(int), sendString.c_str(), sendString.size());
	int byteNum = write(fd, sbuf, sendLength);
	if (byteNum != sendLength) {
	    std::cout << "Error when write to send buffer!" << std::endl;
	}
	return;
}


int Client::recvMsg(DroneState * msg, std::vector<DroneState>& recvMsg)
{
	char buf[sizeof(int)];
	int len = read(fd, buf, sizeof(int));
	if (len == sizeof(int))
	{	
		int recvLength;
		memcpy(&recvLength, buf, sizeof(int));
		char rbuf[recvLength];
		char* cur = rbuf;
		int rlen = read(fd, cur,recvLength);
		while(rlen<recvLength){
		recvLength-=rlen;
		cur+=rlen;
		rlen = read(fd,cur,recvLength);
		}
		// std::cout<<rbuf<<std::endl;
		msg->getMsg(rbuf, recvMsg);
	}
	else if (len == 0)
	{
		return 0;
	}
	else
	{
		return -1;
	}
	return len;
}

int Client::recvMsg(DroneState * msg, std::vector<DroneState>& recvMsgs, ControlMsg& controlMsg)
{
	char buf[sizeof(int)];
	int len = read(fd, buf, sizeof(int));
	if (len == sizeof(int))
	{	
		int recvLength;
		memcpy(&recvLength, buf, sizeof(int));
		char rbuf[recvLength];
		char* cur = rbuf;
		int rlen = read(fd, cur,recvLength);
		while(rlen<recvLength){
		recvLength-=rlen;
		cur+=rlen;
		rlen = read(fd,cur,recvLength);
		}
		// std::cout<<rbuf<<std::endl;
		msg->getMsg(rbuf, recvMsgs, controlMsg);
	}
	else if (len == 0)
	{
		return 0;
	}
	else
	{
		return -1;
	}
	return len;
}

Client::Client(int fileDescriper, sockaddr_in * arg)
{
	addr = arg;
	fd = fileDescriper;
	int ret = connect(fd, (struct sockaddr*)addr, sizeof(*addr));
	if (ret == -1)
	{
		perror("connect");
		exit(0);
	}
}


Client::Client()
{
	addr = nullptr;
	fd = -1;
}
